package br.com.locasis.funcionalidades;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.ServletContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.international.StatusMessages;

import br.com.locasis.entity.Agendamento;
import br.com.locasis.entity.Aluguel;
import br.com.locasis.entity.AluguelProduto;
import br.com.locasis.entity.Automovel;
import br.com.locasis.entity.Cliente;
import br.com.locasis.entity.Cobertura;
import br.com.locasis.entity.FormaPagamento;
import br.com.locasis.entity.HistoricoAluguel;
import br.com.locasis.entity.Pais;
import br.com.locasis.entity.Produto;
import br.com.locasis.entity.TabelaValorAutomovel;
import br.com.locasis.entity.TipoValorPagamento;
import br.com.locasis.entity.Usuario;
import br.com.locasis.entity.ValorPagamento;
import br.com.locasis.utilitarios.DataUtil;
import br.com.locasis.utilitarios.NumeroPorExtenso;
import br.com.locasis.utilitarios.UtilDate;
import br.com.locasis.utilitarios.UtilUfs;

@Name("cadastrarAluguel")
@Scope(ScopeType.CONVERSATION)
// @Restrict(value="#{identity.hasRole('"+PerfilUsuario.PERFIL_PETSHOP+"')}")
public class CadastrarAluguel {

	@In(create = true)
	private EntityManager entityManager;

	@In(create = true)
	private DominioController dominioController;

	@In(required = false)
	Usuario usuarioLogado;

	@In(value = "statusMessages")
	protected StatusMessages messages;

	private Aluguel aluguelEdicao;

	private Agendamento agendamentoSelecionado;

	private Cobertura coberturaEdicao;

	private Aluguel aluguelSelecionado;

	private Aluguel aluguelSalvo;

	private HistoricoAluguel historicoEdicao;

	private List<Aluguel> listaAlugueis;

	private List<Aluguel> listaAlugueisFinalizados;

	private List<HistoricoAluguel> listaHistoricosAluguel;

	private List<Automovel> listaAutomoveis;

	private List<Cliente> listaClientes;

	private List<SelectItem> listaFormasPagamento;

	private List<SelectItem> listaUsuariosAutorizacao;

	private List<SelectItem> listaTabelasValor;

	private List<SelectItem> listaUfs;

	private List<AluguelProduto> listaProdutos;

	private Date dataAluguel;

	private Automovel automovelPesquisa;

	private Automovel automovelSelecionado;

	private Cliente clientePesquisa;

	private Cliente clienteSelecionado;

	private Integer idFormaPagamento;

	private Integer idTabelaSelecionada;

	private Integer idPaisCondutor;

	private String selectedTab;

	private ValorPagamento valorKmExtra;

	private ValorPagamento valorHoraExtra;

	private ValorPagamento valorDiarias;

	private ValorPagamento valorTaxaServico;

	private ValorPagamento valorTotal;

	private ValorPagamento valorCombustivel;

	private ValorPagamento valorTaxaLimpeza;

	private ValorPagamento valorProdutos;

	private boolean selecionadoTodos;

	private boolean finalizacao;

	private AluguelProduto produtoEdicao;

	private Integer idProdutoSelecionado;

	private Integer idUsuarioSelecionado;

	private List<SelectItem> produtos;

	private boolean edicaoProduto;

	private ValorPagamento valorDesconto;

	private boolean exibeModalDesconto;

	private boolean exibeModalRespostaDesconto;

	private boolean exibeModalConfirmacaoDesconto;

	private String filterValue;

	private String filterValueFin;

	public String getFilterValueFin() {
		return filterValueFin;
	}

	public void setFilterValueFin(String filterValueFin) {
		this.filterValueFin = filterValueFin;
	}

	public String getFilterValue() {
		return filterValue;
	}

	public void setFilterValue(String filterValue) {
		this.filterValue = filterValue;
	}

	public boolean isExibeModalConfirmacaoDesconto() {
		return exibeModalConfirmacaoDesconto;
	}

	public void setExibeModalConfirmacaoDesconto(boolean exibeModalConfirmacaoDesconto) {
		this.exibeModalConfirmacaoDesconto = exibeModalConfirmacaoDesconto;
	}

	public boolean isExibeModalDesconto() {
		return exibeModalDesconto;
	}

	public void setExibeModalDesconto(boolean exibeModalDesconto) {
		this.exibeModalDesconto = exibeModalDesconto;
	}

	public boolean isExibeModalRespostaDesconto() {
		return exibeModalRespostaDesconto;
	}

	public void setExibeModalRespostaDesconto(boolean exibeModalRespostaDesconto) {
		this.exibeModalRespostaDesconto = exibeModalRespostaDesconto;
	}

	public ValorPagamento getValorDesconto() {
		return valorDesconto;
	}

	public void setValorDesconto(ValorPagamento valorDesconto) {
		this.valorDesconto = valorDesconto;
	}

	public ValorPagamento getValorProdutos() {
		if (valorProdutos == null) {
			valorProdutos = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.PRODUTOS));
		}
		return valorProdutos;
	}

	public void setValorProdutos(ValorPagamento valorProdutos) {
		this.valorProdutos = valorProdutos;
	}

	public boolean isEdicaoProduto() {
		return edicaoProduto;
	}

	public void setEdicaoProduto(boolean edicaoProduto) {
		this.edicaoProduto = edicaoProduto;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> getProdutos() {
		if (produtos == null) {
			produtos = new ArrayList<SelectItem>();
			produtos.add(new SelectItem(null, "Selecione"));
			List<Produto> lista = (List<Produto>) entityManager.createQuery("select p from Produto p where p.flgAtivo is true").getResultList();
			for (Produto p : lista) {
				produtos.add(new SelectItem(p.getIdProduto(), p.getNome()));
			}
		}
		return produtos;
	}

	public void setProdutos(List<SelectItem> produtos) {
		this.produtos = produtos;
	}

	public Integer getIdProdutoSelecionado() {
		return idProdutoSelecionado;
	}

	public void setIdProdutoSelecionado(Integer idProdutoSelecionado) {
		this.idProdutoSelecionado = idProdutoSelecionado;
	}

	public Integer getIdUsuarioSelecionado() {
		return idUsuarioSelecionado;
	}

	public void setIdUsuarioSelecionado(Integer idUsuarioSelecionado) {
		this.idUsuarioSelecionado = idUsuarioSelecionado;
	}

	public AluguelProduto getProdutoEdicao() {
		if (produtoEdicao == null) {
			produtoEdicao = new AluguelProduto();
			produtoEdicao.setProduto(new Produto());
		}
		return produtoEdicao;
	}

	public void setProdutoEdicao(AluguelProduto produtoEdicao) {
		this.produtoEdicao = produtoEdicao;
	}

	public List<AluguelProduto> getListaProdutos() {
		if (listaProdutos == null) {
			listaProdutos = new ArrayList<AluguelProduto>();
		}
		return listaProdutos;
	}

	public void setListaProdutos(List<AluguelProduto> listaProdutos) {
		this.listaProdutos = listaProdutos;
	}

	public boolean isFinalizacao() {
		return finalizacao;
	}

	public void setFinalizacao(boolean finalizacao) {
		this.finalizacao = finalizacao;
	}

	public boolean isSelecionadoTodos() {
		return selecionadoTodos;
	}

	public void setSelecionadoTodos(boolean selecionadoTodos) {
		this.selecionadoTodos = selecionadoTodos;
	}

	public ValorPagamento getValorKmExtra() {
		if (valorKmExtra == null) {
			valorKmExtra = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.KM_EXTRA));
		}
		return valorKmExtra;
	}

	public void setValorKmExtra(ValorPagamento valorKmExtra) {
		this.valorKmExtra = valorKmExtra;
	}

	public ValorPagamento getValorHoraExtra() {
		if (valorHoraExtra == null) {
			valorHoraExtra = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.HORA_EXTRA));
		}
		return valorHoraExtra;
	}

	public void setValorHoraExtra(ValorPagamento valorHoraExtra) {
		this.valorHoraExtra = valorHoraExtra;
	}

	public ValorPagamento getValorDiarias() {
		if (valorDiarias == null) {
			valorDiarias = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.DIARIAS));
		}
		return valorDiarias;
	}

	public void atualizaProdutoListener(ValueChangeEvent evento) {
		if (evento.getNewValue() != null) {
			getProdutoEdicao().setProduto(entityManager.find(Produto.class, (Integer) evento.getNewValue()));
		}
	}

	public void selecionaTabelaListener(ValueChangeEvent evento) {
		if (evento != null && evento.getNewValue() != null) {
			idTabelaSelecionada = (Integer) evento.getNewValue();
		}
	}

	public void selecionarValorPagamento(ValorPagamento valor) {
		valorDesconto = valor;
	}

	public byte[] recuperaFoto(String url) {
		try {
			InputStream is = null;
			byte[] buffer = null;
			is = new FileInputStream(url);
			buffer = new byte[is.available()];
			is.read(buffer);
			is.close();
			return buffer;
		} catch (FileNotFoundException e) {
			System.out.println("File Not Found.");
			e.printStackTrace();
		} catch (IOException e1) {
			System.out.println("Error Reading The File.");
			e1.printStackTrace();
		}
		return null;
	}

	public void lancarDesconto() {
		if (usuarioLogado == null) {
			getValorDesconto().setDesconto(BigDecimal.valueOf(0));
			messages.add(Severity.ERROR, "O usuário administrador não pode lançar descontos.");
			return;
		} else if (usuarioLogado.getPerfil().getVlrMaxDesconto() == null || usuarioLogado.getPerfil().getVlrMaxDesconto().equals(0F)) {
			getValorDesconto().setDesconto(BigDecimal.valueOf(0));
			messages.add(Severity.ERROR, "O seu perfil não tem permissão para lançar desconto.");
			return;
		}
		if (getValorDesconto().getTipoDesconto() != null) {
			if (getValorDesconto().getTipoDesconto().equals(1)) {
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// if (getValorDesconto().getDesconto() > usuarioLogado.getPerfil().getVlrMaxDesconto()) {
				if (getValorDesconto().getDesconto().compareTo(usuarioLogado.getPerfil().getVlrMaxDesconto()) == 1) {
					getValorDesconto().setDesconto(BigDecimal.valueOf(0));
					messages.add(Severity.ERROR, "Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
					return;
				}
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// Float valor = 0F;
				BigDecimal valor = BigDecimal.valueOf(0);
				if (getValorDesconto().getValorUnitario() != null)
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// valor = getValorDesconto().getValorUnitario() * (1 - (getValorDesconto().getDesconto() / 100));
					valor = getValorDesconto().getValorUnitario().multiply(BigDecimal.valueOf(1).subtract(getValorDesconto().getDesconto().divide(BigDecimal.valueOf(100))));
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// if (getValorDesconto().getQuantidade() != null && valor >= 0)
				if (getValorDesconto().getQuantidade() != null && (valor.compareTo(BigDecimal.ZERO) == 0 || valor.compareTo(BigDecimal.ZERO) == 1))
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// getValorDesconto().setTotal(valor * getValorDesconto().getQuantidade());
					getValorDesconto().setTotal(valor.multiply(BigDecimal.valueOf(getValorDesconto().getQuantidade())));
			} else {
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// Float valor = 0F;
				BigDecimal valor = BigDecimal.valueOf(0);
				if (getValorDesconto().getValorUnitario() != null && getValorDesconto().getQuantidade() != null) {
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// Float percentual = (getValorDesconto().getDesconto() * 100) / (getValorDesconto().getValorUnitario() * getValorDesconto().getQuantidade());
					BigDecimal percentual = (getValorDesconto().getDesconto().multiply(BigDecimal.valueOf(100))).divide((getValorDesconto().getValorUnitario().multiply(BigDecimal.valueOf(getValorDesconto().getQuantidade()))));
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// if (percentual > usuarioLogado.getPerfil().getVlrMaxDesconto()) {
					if (percentual.compareTo(usuarioLogado.getPerfil().getVlrMaxDesconto()) == 1) {
						// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
						// getValorDesconto().setDesconto(0F);
						getValorDesconto().setDesconto(BigDecimal.valueOf(0));
						messages.add(Severity.ERROR, "Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
						return;
					}
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// valor = (getValorDesconto().getValorUnitario() * getValorDesconto().getQuantidade()) - getValorDesconto().getDesconto();
					valor = (getValorDesconto().getValorUnitario().multiply(BigDecimal.valueOf(getValorDesconto().getQuantidade()))).subtract(getValorDesconto().getDesconto());
				}
				getValorDesconto().setTotal(valor);
			}
			atualizaTotalizadores();
			setValorDesconto(null);
		}
	}

	public void atualizaTotalProduto() {
		// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
		// float valorParcial = 0F;
		BigDecimal valorParcial = BigDecimal.valueOf(0);
		if (getProdutoEdicao().getProduto().getIdProduto() != null && getProdutoEdicao().getProduto().getValor() != null) {
			if (getProdutoEdicao().getQuantidade() != null) {
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// valorParcial = getProdutoEdicao().getProduto().getValor() * getProdutoEdicao().getQuantidade();
				valorParcial = getProdutoEdicao().getProduto().getValor().multiply(BigDecimal.valueOf(getProdutoEdicao().getQuantidade()));
				if (getProdutoEdicao().getDesconto() != null) {
					if (getProdutoEdicao().getTipoDesconto() != null) {
						if (getProdutoEdicao().getTipoDesconto().equals(1)) {
							// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
							// valorParcial = valorParcial * (1 - (getProdutoEdicao().getDesconto() / 100));
							valorParcial = valorParcial.multiply((BigDecimal.valueOf(1).subtract((getProdutoEdicao().getDesconto().divide(BigDecimal.valueOf(100))))));
						} else {
							// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
							// valorParcial = valorParcial - getProdutoEdicao().getDesconto();
							valorParcial = valorParcial.subtract(getProdutoEdicao().getDesconto());
						}
					}
				}
			}
		}
		getProdutoEdicao().setValorTotal(valorParcial);
	}

	public void inicializaPopupNovoProduto() {
		setProdutoEdicao(null);
		setIdProdutoSelecionado(null);
		setEdicaoProduto(false);
	}

	public void inicializaPopupEditarProduto(AluguelProduto aluguelProduto) {
		setProdutoEdicao(aluguelProduto);
		setIdProdutoSelecionado(aluguelProduto.getProduto().getIdProduto());
		setEdicaoProduto(true);
	}

	@SuppressWarnings("static-access")
	public String converterAgendaToAluguel(Agendamento agendamentoSelecionado) {
		setAluguelEdicao(new Aluguel());
		setAgendamentoSelecionado(agendamentoSelecionado);
		setAutomovelSelecionado(agendamentoSelecionado.getAutomovel());
		setClienteSelecionado(agendamentoSelecionado.getCliente());
		atualizaListaTabelasValor(getAutomovelSelecionado());
		getAluguelEdicao().setDataSaida(agendamentoSelecionado.getDataInicio());
		getAluguelEdicao().setDataPrevistaEntrega(agendamentoSelecionado.getDataFim());
		getAluguelEdicao().setFlgProprioCondutor(Boolean.TRUE.booleanValue());

		if (DataUtil.getInstance().isDataMaior(agendamentoSelecionado.getDataFim(), agendamentoSelecionado.getDataInicio())) {
			getAluguelEdicao().setTotalDiarias(DataUtil.getInstance().diferencaEmDias(agendamentoSelecionado.getDataInicio(), agendamentoSelecionado.getDataFim()));
		}

		return "agenda_to_aluguel";
	}

	public void salvarNovoProduto() {
		if (getProdutoEdicao().getQuantidade() == null) {
			messages.add(Severity.ERROR, "O campo Quantidade é de preenchimento obrigatório");
			return;
		}
		Produto prod = entityManager.find(Produto.class, getIdProdutoSelecionado());
		getProdutoEdicao().setProduto(prod);
		if (getProdutoEdicao().getDesconto() == null) {
			// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
			// getProdutoEdicao().setDesconto(0F);
			getProdutoEdicao().setDesconto(BigDecimal.valueOf(0));
		} else {
			if (usuarioLogado.getPerfil().getVlrMaxDesconto() == null || usuarioLogado.getPerfil().getVlrMaxDesconto().equals(0F)) {
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// getProdutoEdicao().setDesconto(0F);
				getProdutoEdicao().setDesconto(BigDecimal.valueOf(0));
				// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
				// getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
				getProdutoEdicao().setValorTotal(prod.getValor().multiply(BigDecimal.valueOf(getProdutoEdicao().getQuantidade())));
				messages.add(Severity.ERROR, "O seu perfil não tem permissão para lançar desconto.");
			} else {
				if (getProdutoEdicao().getTipoDesconto().equals(1)) {
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// if (getProdutoEdicao().getDesconto() > usuarioLogado.getPerfil().getVlrMaxDesconto()) {
					if (getProdutoEdicao().getDesconto().compareTo(usuarioLogado.getPerfil().getVlrMaxDesconto()) == 1) {
						messages.add(Severity.ERROR, "Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
						// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
						// getProdutoEdicao().setDesconto(0F);
						getProdutoEdicao().setDesconto(BigDecimal.valueOf(0));
						// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
						// getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
						getProdutoEdicao().setValorTotal(prod.getValor().multiply(BigDecimal.valueOf(getProdutoEdicao().getQuantidade())));
					}
				} else {
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// Float percentual = (getProdutoEdicao().getDesconto() * 100) / (prod.getValor() * getProdutoEdicao().getQuantidade());
					BigDecimal percentual = (getProdutoEdicao().getDesconto().multiply(BigDecimal.valueOf(100))).divide(prod.getValor().multiply(BigDecimal.valueOf(getProdutoEdicao().getQuantidade())));
					// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
					// if (percentual > usuarioLogado.getPerfil().getVlrMaxDesconto()) {
					if (percentual.compareTo(usuarioLogado.getPerfil().getVlrMaxDesconto()) == 1) {
						// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
						// getProdutoEdicao().setDesconto(0F);
						getProdutoEdicao().setDesconto(BigDecimal.valueOf(0));
						// FIXME - MODELO DE IMPLEMENTACAO ANTIGO
						// getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
						getProdutoEdicao().setValorTotal(prod.getValor().multiply(BigDecimal.valueOf(getProdutoEdicao().getQuantidade())));
						messages.add(Severity.ERROR, "Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
					}
				}
			}
		}
		// getProdutoEdicao().setProduto(entityManager.find(Produto.class, getIdProdutoSelecionado()));
		if (!isEdicaoProduto()) {
			getListaProdutos().add(getProdutoEdicao());
		}
		atualizaTotalizadoresProduto();
	}

	public void atualizaTotalizadoresProduto() {
		Integer quantidade = 0;
		BigDecimal desconto = BigDecimal.valueOf(0);
		BigDecimal total = BigDecimal.valueOf(0);
		BigDecimal valorUnitario = BigDecimal.valueOf(0);
		for (AluguelProduto ap : getListaProdutos()) {
			quantidade = quantidade + ap.getQuantidade();
			// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
			// desconto = desconto + ap.getDesconto();
			desconto = desconto.add(ap.getDesconto());
			// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
			// valorUnitario = valorUnitario + ap.getProduto().getValor();
			valorUnitario = valorUnitario.add(ap.getProduto().getValor());
			// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
			// total = total + ap.getValorTotal();
			total = total.add(ap.getValorTotal());
		}
		getValorProdutos().setQuantidade(quantidade);
		getValorProdutos().setDesconto(desconto);
		getValorProdutos().setValorUnitario(valorUnitario);
		getValorProdutos().setTotal(total);
		atualizaTotalizadores();
	}

	public void excluirProduto(AluguelProduto produto) {
		getListaProdutos().remove(produto);
		if (produto.getIdAluguelProduto() != null) {
			entityManager.remove(produto);
			entityManager.flush();
		}
		atualizaTotalizadoresProduto();
		messages.add(Severity.INFO, "Produto excluído com sucesso.");
	}

	public void atualizaValoresDiaria() {
		if (getIdTabelaSelecionada() != null) {
			TabelaValorAutomovel tabelaAuto = entityManager.find(TabelaValorAutomovel.class, getIdTabelaSelecionada());
			if (getAluguelEdicao().getTotalDiarias() != null) {
				getValorDiarias().setQuantidade(getAluguelEdicao().getTotalDiarias());
			}
			if (getAutomovelSelecionado() != null && getAutomovelSelecionado().getValorDiaria() != null) {
				getValorDiarias().setValorUnitario(tabelaAuto.getValorDiaria());
			}
			if (getAluguelEdicao().getTotalDiarias() != null && tabelaAuto.getValorDiaria() != null) {
				// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
				// getValorDiarias().setTotal(getValorDiarias().getQuantidade() * tabelaAuto.getValorDiaria());
				getValorDiarias().setTotal(BigDecimal.valueOf(getValorDiarias().getQuantidade()).multiply(tabelaAuto.getValorDiaria()));
				atualizaTotalizadores();
			}
			getValorHoraExtra().setQuantidade(0);
			getValorHoraExtra().setValorUnitario(tabelaAuto.getValorHora());
			// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
			// getValorHoraExtra().setTotal(0);
			getValorHoraExtra().setTotal(BigDecimal.valueOf(0));

			getValorKmExtra().setQuantidade(0);
			getValorKmExtra().setValorUnitario(tabelaAuto.getValorKm());
			// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
			// getValorKmExtra().setTotal(0F);
			getValorKmExtra().setTotal(BigDecimal.valueOf(0));

			calculaDataPrevistaRetorno();
		}
	}

	public void setValorDiarias(ValorPagamento valorDiarias) {
		this.valorDiarias = valorDiarias;
	}

	public ValorPagamento getValorTaxaServico() {
		if (valorTaxaServico == null) {
			valorTaxaServico = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_SERVICO));
		}
		return valorTaxaServico;
	}

	public void setValorTaxaServico(ValorPagamento valorTaxaServico) {
		this.valorTaxaServico = valorTaxaServico;
	}

	public ValorPagamento getValorTotal() {
		if (valorTotal == null) {
			valorTotal = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TOTAL));
		}
		return valorTotal;
	}

	public void setValorTotal(ValorPagamento valorTotal) {
		this.valorTotal = valorTotal;
	}

	public ValorPagamento getValorCombustivel() {
		if (valorCombustivel == null) {
			valorCombustivel = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.COMBUSTIVEL));
		}
		return valorCombustivel;
	}

	public void setValorCombustivel(ValorPagamento valorCombustivel) {
		this.valorCombustivel = valorCombustivel;
	}

	public ValorPagamento getValorTaxaLimpeza() {
		if (valorTaxaLimpeza == null) {
			valorTaxaLimpeza = new ValorPagamento(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_LIMPEZA));
		}
		return valorTaxaLimpeza;
	}

	public void setValorTaxaLimpeza(ValorPagamento valorTaxaLimpeza) {
		this.valorTaxaLimpeza = valorTaxaLimpeza;
	}

	public String getSelectedTab() {
		return selectedTab;
	}

	public void setSelectedTab(String selectedTab) {
		this.selectedTab = selectedTab;
	}

	public Integer getIdFormaPagamento() {
		return idFormaPagamento;
	}

	public void setIdFormaPagamento(Integer idFormaPagamento) {
		this.idFormaPagamento = idFormaPagamento;
	}

	public Integer getIdTabelaSelecionada() {
		return idTabelaSelecionada;
	}

	public void setIdTabelaSelecionada(Integer idTabelaSelecionada) {
		this.idTabelaSelecionada = idTabelaSelecionada;
	}

	public List<SelectItem> getListaFormasPagamento() {
		if (listaFormasPagamento == null) {
			listaFormasPagamento = new ArrayList<SelectItem>();
			listaFormasPagamento.add(new SelectItem(null, "Selecione"));
			List<FormaPagamento> lista = dominioController.getListaFormasPagamento();
			for (FormaPagamento f : lista) {
				listaFormasPagamento.add(new SelectItem(f.getIdFormaPagamento(), f.getNome()));
			}
		}
		return listaFormasPagamento;
	}

	public void setListaFormasPagamento(List<SelectItem> listaFormasPagamento) {
		this.listaFormasPagamento = listaFormasPagamento;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> getListaUsuariosAutorizacao() {
		if (listaUsuariosAutorizacao == null) {
			listaUsuariosAutorizacao = new ArrayList<SelectItem>();
			listaUsuariosAutorizacao.add(new SelectItem(null, "Selecione"));
			if (usuarioLogado != null && usuarioLogado.getPerfil().getPerfilAutorizacao() != null) {
				List<Usuario> lista = (List<Usuario>) entityManager.createQuery("select u from Usuario u where u.perfil.idPerfil = :idPerfil and u.flgAtivo is true").setParameter("idPerfil", usuarioLogado.getPerfil().getPerfilAutorizacao().getIdPerfil()).getResultList();
				for (Usuario u : lista) {
					listaUsuariosAutorizacao.add(new SelectItem(u.getIdUsuario(), u.getNome()));
				}
			}
		}
		return listaUsuariosAutorizacao;
	}

	public void setListaUsuariosAutorizacao(List<SelectItem> listaUsuariosAutorizacao) {
		this.listaUsuariosAutorizacao = listaUsuariosAutorizacao;
	}

	public List<SelectItem> getListaTabelasValor() {
		if (listaTabelasValor == null) {
			listaTabelasValor = new ArrayList<SelectItem>();
			listaTabelasValor.add(new SelectItem(null, "Selecione"));
		}
		return listaTabelasValor;
	}

	public void setListaTabelasValor(List<SelectItem> listaTabelasValor) {
		this.listaTabelasValor = listaTabelasValor;
	}

	public List<SelectItem> getListaUfs() {
		if (listaUfs == null) {
			listaUfs = UtilUfs.recuperaListaUfsSelectItem();
		}
		return listaUfs;
	}

	public void setListaUfs(List<SelectItem> listaUfs) {
		this.listaUfs = listaUfs;
	}

	public Integer getIdPaisCondutor() {
		return idPaisCondutor;
	}

	public void setIdPaisCondutor(Integer idPaisCondutor) {
		this.idPaisCondutor = idPaisCondutor;
	}

	public Date getDataAluguel() {
		return dataAluguel;
	}

	public void setDataAluguel(Date dataAluguel) {
		this.dataAluguel = dataAluguel;
	}

	public Automovel getAutomovelSelecionado() {
		if (automovelSelecionado == null) {
			automovelSelecionado = new Automovel();
		}
		return automovelSelecionado;
	}

	public void setAutomovelSelecionado(Automovel automovelSelecionado) {
		this.automovelSelecionado = automovelSelecionado;
	}

	public Cliente getClienteSelecionado() {
		if (clienteSelecionado == null) {
			clienteSelecionado = new Cliente();
		}
		return clienteSelecionado;
	}

	public void setClienteSelecionado(Cliente clienteSelecionado) {
		this.clienteSelecionado = clienteSelecionado;
	}

	public Cliente getClientePesquisa() {
		if (clientePesquisa == null) {
			clientePesquisa = new Cliente();
		}
		return clientePesquisa;
	}

	public void setClientePesquisa(Cliente clientePesquisa) {
		this.clientePesquisa = clientePesquisa;
	}

	public Automovel getAutomovelPesquisa() {
		if (automovelPesquisa == null) {
			automovelPesquisa = new Automovel();
		}
		return automovelPesquisa;
	}

	public void setAutomovelPesquisa(Automovel automovelPesquisa) {
		this.automovelPesquisa = automovelPesquisa;
	}

	public void mudarAba(String idAba) {
		setSelectedTab(idAba);
	}

	public void onLoad() {
		setListaAlugueis(null);
		setListaAutomoveis(null);
		setListaClientes(null);
		setClientePesquisa(null);
		setAutomovelPesquisa(null);
		if (aluguelSelecionado != null) {
			aluguelEdicao = aluguelSelecionado;
			Calendar dataSaida = Calendar.getInstance();
			Calendar dataPrevRetorno = Calendar.getInstance();
			dataSaida.setTime(aluguelEdicao.getDataSaida());
			dataPrevRetorno.setTime(getAluguelEdicao().getDataPrevistaEntrega());

			aluguelEdicao.setHoraSaida(dataSaida.get(Calendar.HOUR_OF_DAY));
			aluguelEdicao.setMinutoSaida(dataSaida.get(Calendar.MINUTE));
			aluguelEdicao.setHoraPrevRetorno(dataPrevRetorno.get(Calendar.HOUR_OF_DAY));
			aluguelEdicao.setMinutoPrevRetorno(dataPrevRetorno.get(Calendar.MINUTE));

			if (aluguelEdicao.getDataRetorno() != null) {
				Calendar dataRetorno = Calendar.getInstance();
				dataRetorno.setTime(aluguelEdicao.getDataRetorno());
				aluguelEdicao.setHoraRetorno(dataRetorno.get(Calendar.HOUR_OF_DAY));
				aluguelEdicao.setMinutoRetorno(dataRetorno.get(Calendar.MINUTE));
			}
		}
	}

	public boolean filterIds(Object current) {
		Aluguel currentAluguel = (Aluguel) current;
		if (filterValue == null || filterValue.length() == 0) {
			return true;
		}
		if (currentAluguel.getIdAluguel().toString().startsWith(filterValue.toLowerCase())) {
			return true;
		} else {
			return false;
		}
	}

	public boolean filterIdsFinalizados(Object current) {
		Aluguel currentAluguel = (Aluguel) current;
		if (filterValueFin == null || filterValueFin.length() == 0) {
			return true;
		}
		if (currentAluguel.getIdAluguel().toString().startsWith(filterValueFin.toLowerCase())) {
			return true;
		} else {
			return false;
		}
	}

	public void onLoadList() {
		setSelectedTab("tabDadosVeiculo");
		setAluguelEdicao(null);
		setCoberturaEdicao(null);
		aluguelSelecionado = null;
	}

	@SuppressWarnings("unchecked")
	public void pesquisaClientes() {
		StringBuffer query = new StringBuffer("select c from Cliente c where c.flgAtivo is true ");
		if (getClientePesquisa().getNome() != null && !getClientePesquisa().getNome().isEmpty()) {
			query.append(" and UPPER(c.nome) like UPPER(:nome)");
		}
		if (getClientePesquisa().getCpf() != null && !getClientePesquisa().getCpf().isEmpty()) {
			query.append(" and c.cpf = :cpf");
		}
		if (getClientePesquisa().getPassaporte() != null && !getClientePesquisa().getPassaporte().isEmpty()) {
			query.append(" and c.passaporte = :passaporte");
		}
		if (getClientePesquisa().getNroCartaoGold() != null && !getClientePesquisa().getNroCartaoGold().isEmpty()) {
			query.append(" and c.nroCartaoGold = :nroCartao");
		}

		Query qryResult = entityManager.createQuery(query.toString());

		if (getClientePesquisa().getNome() != null && !getClientePesquisa().getNome().isEmpty()) {
			qryResult.setParameter("nome", "%" + getClientePesquisa().getNome() + "%");
		}
		if (getClientePesquisa().getCpf() != null && !getClientePesquisa().getCpf().isEmpty()) {
			qryResult.setParameter("cpf", getClientePesquisa().getCpf());
		}
		if (getClientePesquisa().getPassaporte() != null && !getClientePesquisa().getPassaporte().isEmpty()) {
			qryResult.setParameter("passaporte", getClientePesquisa().getPassaporte());
			query.append(" and c.passaporte = :passaporte");
		}
		if (getClientePesquisa().getNroCartaoGold() != null && !getClientePesquisa().getNroCartaoGold().isEmpty()) {
			qryResult.setParameter("nroCartao", getClientePesquisa().getNroCartaoGold());
			query.append(" and c.nroCartaoGold = :nroCartao");
		}

		listaClientes = (List<Cliente>) qryResult.getResultList();
	}

	public void atualizaValores(ValorPagamento pagamento) {
		if (pagamento.getQuantidade() != null) {
			if (pagamento.getValorUnitario() != null) {
				// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
				// pagamento.setTotal(pagamento.getQuantidade() * pagamento.getValorUnitario());
				pagamento.setTotal(BigDecimal.valueOf(pagamento.getQuantidade()).multiply(pagamento.getValorUnitario()));
			}
			if (pagamento.getDesconto() != null && pagamento.getTotal() != null) {
				// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
				// pagamento.setTotal(pagamento.getTotal() - pagamento.getDesconto());
				pagamento.setTotal(pagamento.getTotal().subtract(pagamento.getDesconto()));
			}
			atualizaTotalizadores();
		}
	}

	public void atualizaValoresPagamento() {
		atualizaValores(getValorKmExtra());
		atualizaValores(getValorHoraExtra());
		atualizaValores(getValorDiarias());
		atualizaValores(getValorCombustivel());
		atualizaValores(getValorTaxaLimpeza());
		atualizaValores(getValorTaxaServico());

		setValorDesconto(getValorKmExtra());
		lancarDesconto();
		setValorDesconto(getValorHoraExtra());
		lancarDesconto();
		setValorDesconto(getValorDiarias());
		lancarDesconto();
		setValorDesconto(getValorCombustivel());
		lancarDesconto();
		setValorDesconto(getValorTaxaLimpeza());
		lancarDesconto();
		setValorDesconto(getValorTaxaServico());
		lancarDesconto();
	}

	public void atualizaTotalizadores() {
		getValorTotal().setQuantidade(null);
		getValorTotal().setValorUnitario(null);
		getValorTotal().setDesconto(null);
		getValorTotal().setTotal(null);
		int contQtdeKmExtra = getValorKmExtra().getQuantidade() != null ? getValorKmExtra().getQuantidade() : 0;
		int contQtdeHoraExtra = getValorHoraExtra().getQuantidade() != null ? getValorHoraExtra().getQuantidade() : 0;
		int contQtdeDiarias = getValorDiarias().getQuantidade() != null ? getValorDiarias().getQuantidade() : 0;
		int contQtdeTaxaServico = getValorTaxaServico().getQuantidade() != null ? getValorTaxaServico().getQuantidade() : 0;
		int contQtdeCombustivel = getValorCombustivel().getQuantidade() != null ? getValorCombustivel().getQuantidade() : 0;
		int contQtdeTaxaLimpeza = getValorTaxaLimpeza().getQuantidade() != null ? getValorTaxaLimpeza().getQuantidade() : 0;
		int contQtdeProdutos = getValorProdutos().getQuantidade() != null ? getValorProdutos().getQuantidade() : 0;
		getValorTotal().setQuantidade(contQtdeKmExtra + contQtdeHoraExtra + contQtdeDiarias + contQtdeTaxaServico + contQtdeCombustivel + contQtdeTaxaLimpeza + contQtdeProdutos);

		BigDecimal contValorKmExtra = getValorKmExtra().getValorUnitario() != null ? getValorKmExtra().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorHoraExtra = getValorHoraExtra().getValorUnitario() != null ? getValorHoraExtra().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorDiarias = getValorDiarias().getValorUnitario() != null ? getValorDiarias().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorTaxaServico = getValorTaxaServico().getValorUnitario() != null ? getValorTaxaServico().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorCombustivel = getValorCombustivel().getValorUnitario() != null ? getValorCombustivel().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorTaxaLimpeza = getValorTaxaLimpeza().getValorUnitario() != null ? getValorTaxaLimpeza().getValorUnitario() : BigDecimal.valueOf(0);
		BigDecimal contValorProdutos = getValorProdutos().getValorUnitario() != null ? getValorProdutos().getValorUnitario() : BigDecimal.valueOf(0);
		// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
		// getValorTotal().setValorUnitario(contValorKmExtra + contValorHoraExtra + contValorDiarias + contValorTaxaServico + contValorCombustivel + contValorTaxaLimpeza + contValorProdutos);
		getValorTotal().setValorUnitario(contValorKmExtra.add(contValorHoraExtra).add(contValorDiarias).add(contValorTaxaServico).add(contValorCombustivel).add(contValorTaxaLimpeza).add(contValorProdutos));

		BigDecimal contDescontoKmExtra = getValorKmExtra().getDesconto() != null ? getValorKmExtra().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoHoraExtra = getValorHoraExtra().getDesconto() != null ? getValorHoraExtra().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoDiarias = getValorDiarias().getDesconto() != null ? getValorDiarias().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoTaxaServico = getValorTaxaServico().getDesconto() != null ? getValorTaxaServico().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoCombustivel = getValorCombustivel().getDesconto() != null ? getValorCombustivel().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoTaxaLimpeza = getValorTaxaLimpeza().getDesconto() != null ? getValorTaxaLimpeza().getDesconto() : BigDecimal.valueOf(0);
		BigDecimal contDescontoProdutos = getValorProdutos().getDesconto() != null ? getValorProdutos().getDesconto() : BigDecimal.valueOf(0);
		// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
		// getValorTotal().setDesconto(contDescontoKmExtra + contDescontoHoraExtra + contDescontoDiarias + contDescontoTaxaServico + contDescontoCombustivel + contDescontoTaxaLimpeza);
		getValorTotal().setDesconto(contDescontoKmExtra.add(contDescontoHoraExtra).add(contDescontoDiarias).add(contDescontoTaxaServico).add(contDescontoCombustivel).add(contDescontoTaxaLimpeza));

		BigDecimal contTotalKmExtra = getValorKmExtra().getTotal() != null ? getValorKmExtra().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalHoraExtra = getValorHoraExtra().getTotal() != null ? getValorHoraExtra().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalDiarias = getValorDiarias().getTotal() != null ? getValorDiarias().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalTaxaServico = getValorTaxaServico().getTotal() != null ? getValorTaxaServico().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalCombustivel = getValorCombustivel().getTotal() != null ? getValorCombustivel().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalTaxaLimpeza = getValorTaxaLimpeza().getTotal() != null ? getValorTaxaLimpeza().getTotal() : BigDecimal.valueOf(0);
		BigDecimal contTotalProdutos = getValorProdutos().getTotal() != null ? getValorProdutos().getTotal() : BigDecimal.valueOf(0);
		// FIXME - MODELO ANTIGO DE IMPLEMENTACAO
		// getValorTotal().setTotal(contTotalKmExtra + contTotalHoraExtra + contTotalDiarias + contTotalTaxaServico + contTotalCombustivel + contTotalTaxaLimpeza + contTotalProdutos);
		getValorTotal().setTotal(contTotalKmExtra.add(contTotalHoraExtra).add(contTotalDiarias).add(contTotalTaxaServico).add(contTotalCombustivel).add(contTotalTaxaLimpeza).add(contTotalProdutos));

	}

	@SuppressWarnings("unchecked")
	public void pesquisaAutomoveis() {
		StringBuffer query = new StringBuffer("select a from Automovel a where a.flgAtivo is true ");
		if (getAutomovelPesquisa().getMarca() != null && !getAutomovelPesquisa().getMarca().isEmpty()) {
			query.append("and UPPER(a.marca) = UPPER(:marca)");
		}
		if (getAutomovelPesquisa().getModelo() != null && !getAutomovelPesquisa().getModelo().isEmpty()) {
			query.append("and UPPER(a.modelo) = UPPER(:modelo)");
		}
		if (getAutomovelPesquisa().getPlaca() != null && !getAutomovelPesquisa().getPlaca().isEmpty()) {
			query.append("and UPPER(a.placa) = UPPER(:placa)");
		}
		if (getAutomovelPesquisa().getCor() != null && !getAutomovelPesquisa().getCor().isEmpty()) {
			query.append("and UPPER(a.cor) = UPPER(:cor)");
		}
		if (getAutomovelPesquisa().getChassi() != null && !getAutomovelPesquisa().getChassi().isEmpty()) {
			query.append("and UPPER(a.chassi) = UPPER(:chassi)");
		}
		if (getAutomovelPesquisa().getAnoModelo() != null) {
			query.append("and UPPER(a.anoModelo) = UPPER(:anoModelo)");
		}
		if (getAutomovelPesquisa().getAnoFabricacao() != null) {
			query.append("and UPPER(a.anoFabricacao) = UPPER(:anoFabricacao)");
		}

		Query qryResult = entityManager.createQuery(query.toString());

		if (getAutomovelPesquisa().getMarca() != null && !getAutomovelPesquisa().getMarca().isEmpty()) {
			qryResult.setParameter("marca", "%" + getAutomovelPesquisa().getMarca() + "%");
		}
		if (getAutomovelPesquisa().getModelo() != null && !getAutomovelPesquisa().getModelo().isEmpty()) {
			qryResult.setParameter("modelo", "%" + getAutomovelPesquisa().getModelo() + "%");
		}
		if (getAutomovelPesquisa().getPlaca() != null && !getAutomovelPesquisa().getPlaca().isEmpty()) {
			qryResult.setParameter("placa", getAutomovelPesquisa().getPlaca());
		}
		if (getAutomovelPesquisa().getCor() != null && !getAutomovelPesquisa().getCor().isEmpty()) {
			qryResult.setParameter("cor", getAutomovelPesquisa().getCor());
		}
		if (getAutomovelPesquisa().getChassi() != null && !getAutomovelPesquisa().getChassi().isEmpty()) {
			qryResult.setParameter("chassi", getAutomovelPesquisa().getChassi());
		}
		if (getAutomovelPesquisa().getAnoModelo() != null) {
			qryResult.setParameter("anoModelo", getAutomovelPesquisa().getAnoModelo());
		}
		if (getAutomovelPesquisa().getAnoFabricacao() != null) {
			qryResult.setParameter("anoFabricacao", getAutomovelPesquisa().getAnoFabricacao());
		}

		listaAutomoveis = (List<Automovel>) qryResult.getResultList();
	}

	public void selecionarAutomovel(Automovel automovel) {
		automovelSelecionado = automovel;
		atualizaListaTabelasValor(automovel);
	}

	@SuppressWarnings("unchecked")
	public void atualizaListaTabelasValor(Automovel automovel) {
		List<TabelaValorAutomovel> lista = (List<TabelaValorAutomovel>) entityManager.createQuery("select t from TabelaValorAutomovel t where t.automovel.idAutomovel = :id and t.flgAtivo is true").setParameter("id", automovel.getIdAutomovel()).getResultList();
		setListaTabelasValor(null);
		for (TabelaValorAutomovel t : lista) {
			getListaTabelasValor().add(new SelectItem(t.getIdTabelaValorAutomovel(), t.getTabelaValor().getDscTabela()));
		}
	}

	public void selecionarCliente(Cliente cliente) {
		clienteSelecionado = cliente;
	}

	public Aluguel getAluguelEdicao() {
		if (aluguelEdicao == null) {
			aluguelEdicao = new Aluguel();
		}
		return aluguelEdicao;
	}

	public void setAluguelEdicao(Aluguel aluguelEdicao) {
		this.aluguelEdicao = aluguelEdicao;
	}

	public Cobertura getCoberturaEdicao() {
		if (coberturaEdicao == null) {
			coberturaEdicao = new Cobertura();
		}
		return coberturaEdicao;
	}

	public void setCoberturaEdicao(Cobertura coberturaEdicao) {
		this.coberturaEdicao = coberturaEdicao;
	}

	public Aluguel getAluguelSelecionado() {
		return aluguelSelecionado;
	}

	public void setAluguelSelecionado(Aluguel aluguelSelecionado) {
		this.aluguelSelecionado = aluguelSelecionado;
	}

	public HistoricoAluguel getHistoricoEdicao() {
		if (historicoEdicao == null) {
			historicoEdicao = new HistoricoAluguel();
		}
		return historicoEdicao;
	}

	public void setHistoricoEdicao(HistoricoAluguel historicoEdicao) {
		this.historicoEdicao = historicoEdicao;
	}

	@SuppressWarnings("unchecked")
	public List<Aluguel> getListaAlugueis() {
		if (listaAlugueis == null) {
			listaAlugueis = (List<Aluguel>) entityManager.createQuery("select a from Aluguel a where a.flgAtivo is true and a.dataRetorno is null order by a.idAluguel DESC").getResultList();
			for (Aluguel a : listaAlugueis) {
				Long cont = 0L;
				cont = (Long) entityManager.createQuery("select COUNT(a.idHistoricoAluguel) from HistoricoAluguel a where a.aluguel.idAluguel = :idAluguel and a.status = 'SOLICITADO' and a.flgAtivo is true").setParameter("idAluguel", a.getIdAluguel()).getSingleResult();
				a.setShowIconeAlerta(cont > 0);
			}
		}
		return listaAlugueis;
	}

	public void setListaAlugueis(List<Aluguel> listaAlugueis) {
		this.listaAlugueis = listaAlugueis;
	}

	@SuppressWarnings("unchecked")
	public List<Aluguel> getListaAlugueisFinalizados() {
		if (listaAlugueisFinalizados == null) {
			listaAlugueisFinalizados = (List<Aluguel>) entityManager.createQuery("select a from Aluguel a where a.dataRetorno is not null and a.flgAtivo is true order by a.idAluguel DESC").getResultList();
		}
		return listaAlugueisFinalizados;
	}

	public void setListaAlugueisFinalizados(List<Aluguel> listaAlugueisFinalizados) {
		this.listaAlugueisFinalizados = listaAlugueisFinalizados;
	}

	@SuppressWarnings("unchecked")
	public List<HistoricoAluguel> getListaHistoricosAluguel() {
		if (listaHistoricosAluguel == null) {
			if (getAluguelEdicao() != null && getAluguelEdicao().getIdAluguel() != null) {
				listaHistoricosAluguel = (List<HistoricoAluguel>) entityManager.createQuery("select h from HistoricoAluguel h where h.aluguel.idAluguel = :idAluguel and h.flgAtivo is true order by h.dtaHistorico DESC").setParameter("idAluguel", getAluguelEdicao().getIdAluguel()).getResultList();
			} else {
				listaHistoricosAluguel = new ArrayList<HistoricoAluguel>();
			}
		}
		return listaHistoricosAluguel;
	}

	public void setListaHistoricosAluguel(List<HistoricoAluguel> listaHistoricosAluguel) {
		this.listaHistoricosAluguel = listaHistoricosAluguel;
	}

	public List<Cliente> getListaClientes() {
		if (listaClientes == null) {
			listaClientes = new ArrayList<Cliente>();
		}
		return listaClientes;
	}

	public void setListaClientes(List<Cliente> listaClientes) {
		this.listaClientes = listaClientes;
	}

	public List<Automovel> getListaAutomoveis() {
		if (listaAutomoveis == null) {
			listaAutomoveis = new ArrayList<Automovel>();
		}
		return listaAutomoveis;
	}

	public void setListaAutomoveis(List<Automovel> listaAutomoveis) {
		this.listaAutomoveis = listaAutomoveis;
	}

	public Agendamento getAgendamentoSelecionado() {
		if (agendamentoSelecionado == null) {
			agendamentoSelecionado = new Agendamento();
		}
		return agendamentoSelecionado;
	}

	public void setAgendamentoSelecionado(Agendamento agendamentoSelecionado) {
		this.agendamentoSelecionado = agendamentoSelecionado;
	}

	public void calculaDataPrevistaRetorno() {
		if (getAluguelEdicao().getDataSaida() != null && getAluguelEdicao().getTotalDiarias() != null) {
			getAluguelEdicao().setDataPrevistaEntrega(UtilDate.getDataAcrescidaDias(getAluguelEdicao().getDataSaida(), getAluguelEdicao().getTotalDiarias()));
		}
	}

	public String salvar() {
		if (usuarioLogado == null) {
			messages.add(Severity.ERROR, "O usuário administrador não pode cadastrar/editar/finalizar aluguel.");
			return null;
		}
		if (UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataPrevistaEntrega(), getAluguelEdicao().getDataSaida())) {
			messages.add(Severity.ERROR, "A data de saída não pode ser maior que a data prevista para retorno.");
			return null;
		}
		if (isFinalizacao()) {
			if (getAluguelEdicao().getDataRetorno() == null) {
				messages.add(Severity.ERROR, "A data de retorno é de preenchimento obrigatório.");
				return null;
			}
			if (getAluguelEdicao().getKmRetorno() == null) {
				messages.add(Severity.ERROR, "O km de retorno é de preenchimento obrigatório.");
				return null;
			}
			getAluguelEdicao().setUsuarioRecebimento(usuarioLogado);
			if (getAluguelEdicao().getKmSaida() > getAluguelEdicao().getKmRetorno()) {
				messages.add(Severity.ERROR, "O km de saída não pode ser maior que a km de retorno.");
				return null;
			}
			if (UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataRetorno(), getAluguelEdicao().getDataSaida())) {
				messages.add(Severity.ERROR, "A data de saída não pode ser maior que a data de retorno.");
				return null;
			}
		}
		if (getAluguelEdicao().isFlgProprioCondutor()) {
			if (getClienteSelecionado().getHabilitacao() == null || getClienteSelecionado().getHabilitacao().isEmpty() || getClienteSelecionado().getHabilitacaoEmissao() == null || getClienteSelecionado().getHabilitacaoValidade() == null) {
				messages.add(Severity.ERROR, "Os dados da habilitação do cliente não foram todos preenchidos. Cadastre-os e após retorne.");
				return null;
			}
		}

		Calendar dataSaida = Calendar.getInstance();
		dataSaida.setTime(getAluguelEdicao().getDataSaida());
		dataSaida.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraSaida());
		dataSaida.set(Calendar.MINUTE, getAluguelEdicao().getMinutoSaida());
		getAluguelEdicao().setDataSaida(dataSaida.getTime());

		Calendar dataPrevRetorno = Calendar.getInstance();
		dataPrevRetorno.setTime(getAluguelEdicao().getDataPrevistaEntrega());
		dataPrevRetorno.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraPrevRetorno());
		dataPrevRetorno.set(Calendar.MINUTE, getAluguelEdicao().getMinutoPrevRetorno());
		getAluguelEdicao().setDataPrevistaEntrega(dataPrevRetorno.getTime());

		if (getAluguelEdicao().getDataRetorno() != null) {
			Calendar dataRetorno = Calendar.getInstance();
			dataRetorno.setTime(getAluguelEdicao().getDataRetorno());
			dataRetorno.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraRetorno());
			dataRetorno.set(Calendar.MINUTE, getAluguelEdicao().getMinutoRetorno());
			getAluguelEdicao().setDataRetorno(dataRetorno.getTime());
		}

		getAluguelEdicao().setFlgAtivo(true);
		getAluguelEdicao().setAutomovel(getAutomovelSelecionado());
		if (!isFinalizacao() && UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataSaida(), UtilDate.getDataAtual()) && UtilDate.data1MenorOuIgualQueData2(UtilDate.getDataAtual(), getAluguelEdicao().getDataPrevistaEntrega())) {
			getAutomovelSelecionado().setSituacao(Automovel.SITUACAO_ALUGADO);
		} else {
			getAutomovelSelecionado().setSituacao(Automovel.SITUACAO_DISPONIVEL);
		}
		if (isFinalizacao()) {
			getAluguelEdicao().setUsuarioRecebimento(usuarioLogado);
			if (getAluguelEdicao().getKmSaida() > getAluguelEdicao().getKmRetorno()) {
				messages.add(Severity.ERROR, "A km de saída não pode ser maior que a km de retorno.");
				return null;
			}
		}
		entityManager.merge(getAutomovelSelecionado());
		getAluguelEdicao().setCliente(getClienteSelecionado());
		getAluguelEdicao().setFormaPagamento(entityManager.find(FormaPagamento.class, getIdFormaPagamento()));
		getAluguelEdicao().setUsuarioEntrega(usuarioLogado);
		getAluguelEdicao().setTotalAluguel(getValorTotal().getTotal());
		getAluguelEdicao().setTabelaValorAutomovel(entityManager.find(TabelaValorAutomovel.class, getIdTabelaSelecionada()));
		if (getIdPaisCondutor() != null)
			getAluguelEdicao().setPais(entityManager.find(Pais.class, getIdPaisCondutor()));
		aluguelSalvo = entityManager.merge(getAluguelEdicao());
		getValorCombustivel().setAluguel(aluguelSalvo);
		getValorCombustivel().setFlgAtivo(true);
		entityManager.merge(getValorCombustivel());
		getValorDiarias().setAluguel(aluguelSalvo);
		getValorDiarias().setFlgAtivo(true);
		entityManager.merge(getValorDiarias());
		getValorHoraExtra().setAluguel(aluguelSalvo);
		getValorHoraExtra().setFlgAtivo(true);
		entityManager.merge(getValorHoraExtra());
		getValorKmExtra().setAluguel(aluguelSalvo);
		getValorKmExtra().setFlgAtivo(true);
		entityManager.merge(getValorKmExtra());
		getValorTaxaLimpeza().setAluguel(aluguelSalvo);
		getValorTaxaLimpeza().setFlgAtivo(true);
		entityManager.merge(getValorTaxaLimpeza());
		getValorTaxaServico().setAluguel(aluguelSalvo);
		getValorTaxaServico().setFlgAtivo(true);
		entityManager.merge(getValorTaxaServico());
		getValorTotal().setAluguel(aluguelSalvo);
		getValorTotal().setFlgAtivo(true);
		entityManager.merge(getValorTotal());
		getCoberturaEdicao().setAluguel(aluguelSalvo);
		entityManager.merge(getCoberturaEdicao());

		for (AluguelProduto ap : getListaProdutos()) {
			ap.setAluguel(aluguelSalvo);
			entityManager.merge(ap);
		}

		if (getAgendamentoSelecionado() != null && getAgendamentoSelecionado().getIdAgendamento() != null) {
			getAgendamentoSelecionado().setFlgAtivo(Boolean.FALSE.booleanValue());
			entityManager.merge(agendamentoSelecionado);
		}

		entityManager.flush();
		if (isFinalizacao()) {
			messages.add(Severity.INFO, "Aluguel finalizado com sucesso.");
		} else {
			messages.add(Severity.INFO, "Aluguel salvo com sucesso.");
		}
		exibeModalConfirmacaoDesconto = true;
		return null;
	}

	public void limparCampos() {
		setHistoricoEdicao(null);
		aluguelSalvo = null;
		setAluguelEdicao(null);
		setValorCombustivel(null);
		setValorDiarias(null);
		setValorHoraExtra(null);
		setValorKmExtra(null);
		setValorTaxaLimpeza(null);
		setValorTaxaServico(null);
		setValorTotal(null);
		setIdFormaPagamento(null);
		setIdPaisCondutor(null);
	}

	public String novo() {
		setAutomovelSelecionado(null);
		setClienteSelecionado(null);
		setAluguelEdicao(null);
		setValorCombustivel(null);
		setValorDiarias(null);
		setValorHoraExtra(null);
		setValorKmExtra(null);
		setValorTaxaLimpeza(null);
		setValorTaxaServico(null);
		setValorTotal(null);
		setIdFormaPagamento(null);
		setIdPaisCondutor(null);
		setFinalizacao(false);
		return "novo";
	}

	public void excluir() {
		List<Aluguel> listaRemocao = new ArrayList<Aluguel>();
		for (Aluguel a : getListaAlugueis()) {
			if (a.isSelecionado()) {
				a.getAutomovel().setSituacao(Automovel.SITUACAO_DISPONIVEL);
				entityManager.merge(a.getAutomovel());
				a.setFlgAtivo(false);
				entityManager.merge(a);
				listaRemocao.add(a);
			}
		}
		entityManager.flush();
		getListaAlugueis().removeAll(listaRemocao);
		messages.add(Severity.INFO, "Aluguel(eis) excluído(s) com sucesso.");
	}

	@SuppressWarnings("unchecked")
	public String editar(Aluguel aluguel, boolean finalizacao) {
		aluguelSelecionado = aluguel;
		setListaHistoricosAluguel(null);
		setAutomovelSelecionado(aluguel.getAutomovel());
		atualizaListaTabelasValor(getAutomovelSelecionado());
		setClienteSelecionado(aluguel.getCliente());
		setIdTabelaSelecionada(aluguel.getTabelaValorAutomovel() != null ? aluguel.getTabelaValorAutomovel().getIdTabelaValorAutomovel() : null);
		setIdFormaPagamento(aluguel.getFormaPagamento() != null ? aluguel.getFormaPagamento().getIdFormaPagamento() : null);
		setIdPaisCondutor(aluguel.getPais() != null ? aluguel.getPais().getIdPais() : null);
		setValorCombustivel(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.COMBUSTIVEL), aluguel));
		setValorDiarias(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.DIARIAS), aluguel));
		setValorHoraExtra(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.HORA_EXTRA), aluguel));
		setValorKmExtra(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.KM_EXTRA), aluguel));
		setValorTaxaLimpeza(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_LIMPEZA), aluguel));
		setValorTaxaServico(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_SERVICO), aluguel));
		setValorTotal(recuperaValorPagamentoPorTipoEAluguel(dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TOTAL), aluguel));
		setListaProdutos(entityManager.createQuery("select a from AluguelProduto a where a.aluguel.idAluguel = :idAluguel").setParameter("idAluguel", aluguel.getIdAluguel()).getResultList());
		atualizaTotalizadoresProduto();
		atualizaTotalizadores();

		try {
			setCoberturaEdicao((Cobertura) entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel").setParameter("idAluguel", aluguel.getIdAluguel()).getSingleResult());
		} catch (NoResultException e) {
			setCoberturaEdicao(new Cobertura());
		}

		if (finalizacao) {
			setFinalizacao(finalizacao);
		} else {
			if (aluguel.getDataRetorno() != null) {
				setFinalizacao(true);
			} else {
				setFinalizacao(finalizacao);
			}
		}
		return "editar";
	}

	public void selecionaTodos() {
		for (Aluguel a : getListaAlugueis()) {
			a.setSelecionado(isSelecionadoTodos());
		}
	}

	public void selecionaTodosFinalizados() {
		for (Aluguel a : getListaAlugueisFinalizados()) {
			a.setSelecionado(isSelecionadoTodos());
		}
	}

	public ValorPagamento recuperaValorPagamentoPorTipoEAluguel(TipoValorPagamento tipo, Aluguel aluguel) {
		try {
			return (ValorPagamento) entityManager.createQuery("select v from ValorPagamento v where v.tipoValorPagamento.idTipoValorPagamento = :idTipoValorPagamento and v.aluguel.idAluguel = :idAluguel").setParameter("idTipoValorPagamento", tipo.getIdTipoValorPagamento()).setParameter("idAluguel", aluguel.getIdAluguel()).getSingleResult();
		} catch (NoResultException e) {
			return new ValorPagamento(tipo);
		}
	}

	public String cancelar() {
		return "voltar";
	}

	@SuppressWarnings("unchecked")
	public String imprimirContrato(Aluguel aluguel) {
		aluguelSelecionado = aluguel;
		List<ValorPagamento> valores = entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.flgAtivo is true and v.tipoValorPagamento.nome != :nome ").setParameter("idAluguel", aluguelSelecionado.getIdAluguel()).setParameter("nome", TipoValorPagamento.TOTAL).getResultList();
		BigDecimal totalDescontos = BigDecimal.valueOf(0);
		for (ValorPagamento vp : valores) {
			// FIXME - MODELO ANTIGO DE IMPLEMENTAÇÃO
			// totalDescontos += vp.getDesconto() != null ? vp.getDesconto() : 0F;
			totalDescontos.add(vp.getDesconto() != null ? vp.getDesconto() : BigDecimal.valueOf(0));
		}
		aluguelSelecionado.setTotalDescontos(totalDescontos);
		return "contrato";
	}

	public String imprimirAutorizacao(Aluguel aluguel) {
		aluguelSelecionado = aluguel;
		return "autorizacao";
	}

	public String imprimirTermoProtecao(Aluguel aluguel) {
		aluguelSelecionado = aluguel;
		try {
			aluguelSelecionado.setCobertura((Cobertura) entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel").setParameter("idAluguel", aluguel.getIdAluguel()).getSingleResult());
		} catch (NoResultException e) {
			aluguelSelecionado.setCobertura(new Cobertura());
		}
		return "termoProtecao";
	}

	public String imprimirTermoProrrogacao(Aluguel aluguel) {
		aluguelSelecionado = aluguel;
		try {
			aluguelSelecionado.setCobertura((Cobertura) entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel").setParameter("idAluguel", aluguel.getIdAluguel()).getSingleResult());
		} catch (NoResultException e) {
			aluguelSelecionado.setCobertura(new Cobertura());
		}
		return "prorrogacao";
	}

	@SuppressWarnings("unchecked")
	public String imprimirRecibo(Aluguel aluguel) {
		aluguelSelecionado = aluguel;
		aluguelSelecionado.setProdutosAlugados(entityManager.createQuery("select a from AluguelProduto a where a.aluguel.idAluguel = :idAluguel").setParameter("idAluguel", aluguel.getIdAluguel()).getResultList());
		List<ValorPagamento> valores = entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.flgAtivo is true and v.tipoValorPagamento.nome != :nome ").setParameter("idAluguel", aluguel.getIdAluguel()).setParameter("nome", TipoValorPagamento.TOTAL).getResultList();
		BigDecimal totalDescontos = BigDecimal.valueOf(0);
		for (ValorPagamento vp : valores) {
			// FIXME - ESTUDAR NOVA IMPLEMENTAÇÃO
			// totalDescontos += vp.getDesconto() != null ? vp.getDesconto() : BigDecimal.valueOf(0);
			totalDescontos.add(vp.getDesconto() != null ? vp.getDesconto() : BigDecimal.valueOf(0));
		}
		aluguelSelecionado.setTotalDescontos(totalDescontos);
		aluguelSelecionado.setPagamentoDiarias((ValorPagamento) entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.tipoValorPagamento.nome = :nomeTipoValor").setParameter("idAluguel", aluguel.getIdAluguel()).setParameter("nomeTipoValor", TipoValorPagamento.DIARIAS).getSingleResult());
		return "recibo";
	}

	public String recuperaCaminhoImagem(String nomeImagem) {
		FacesContext context1 = FacesContext.getCurrentInstance();
		String caminhoAplicacao = ((ServletContext) context1.getExternalContext().getContext()).getRealPath("/");
		return caminhoAplicacao + "/img/" + nomeImagem;
	}

	public static String valorPorExtenso(double vlr) {
		return null;
	}

	public String salvarSolicitacaoDesconto() {
		getHistoricoEdicao().setAluguel(aluguelSalvo);
		getHistoricoEdicao().setUsuarioSolicitante(usuarioLogado);
		getHistoricoEdicao().setUsuarioSolicitado(entityManager.find(Usuario.class, getIdUsuarioSelecionado()));
		getHistoricoEdicao().setDtaHistorico(new Date());
		getHistoricoEdicao().setFlgAtivo(true);
		getHistoricoEdicao().setUsuarioAtualizacao(usuarioLogado);
		getHistoricoEdicao().setStatus(HistoricoAluguel.STATUS_SOLICITADO);
		entityManager.merge(historicoEdicao);
		exibeModalConfirmacaoDesconto = false;
		exibeModalDesconto = false;
		limparCampos();
		messages.add(Severity.INFO, "Aluguel salvo com sucesso.");
		messages.add(Severity.INFO, "Solicitação de desconto enviada.");
		return "persisted";
	}

	public String exibirModalSolicitacaoDesconto(Boolean exibir) {
		exibeModalConfirmacaoDesconto = false;
		exibeModalDesconto = exibir;
		if (!exibir) {
			limparCampos();
			return "persisted";
		} else {
			return null;
		}
	}

	public void responderSolicitacaoDesconto(HistoricoAluguel historico) {
		HistoricoAluguel resposta = new HistoricoAluguel();
		resposta.setAluguel(historico.getAluguel());
		resposta.setUsuarioAtualizacao(usuarioLogado);
		resposta.setUsuarioSolicitado(historico.getUsuarioSolicitado());
		resposta.setUsuarioSolicitante(historico.getUsuarioSolicitante());
		resposta.setFlgAtivo(true);
		resposta.setVlrDesconto(historico.getVlrDesconto());
		resposta.setHistoricoRespondido(historico);
		setHistoricoEdicao(resposta);
		setExibeModalRespostaDesconto(true);
	}

	public void cancelarResposta() {
		setHistoricoEdicao(null);
		setExibeModalRespostaDesconto(false);
	}

	public void salvarResposta() {
		HistoricoAluguel historicoRespondido = getHistoricoEdicao().getHistoricoRespondido();
		getHistoricoEdicao().setDtaHistorico(new Date());
		entityManager.merge(getHistoricoEdicao());
		historicoRespondido.setStatus(HistoricoAluguel.STATUS_RESPONDIDO);
		entityManager.merge(historicoRespondido);
		entityManager.flush();
		setHistoricoEdicao(null);
		setListaHistoricosAluguel(null);
		getListaHistoricosAluguel();
		messages.add(Severity.INFO, "Resposta enviada com sucesso.");
		setExibeModalRespostaDesconto(false);
	}

	public boolean showColunaResponder(HistoricoAluguel historico) {
		if (usuarioLogado == null) {
			return false;
		}
		return historico != null && historico.getUsuarioSolicitado().getIdUsuario().equals(usuarioLogado.getIdUsuario());
	}

	public String recuperaValorPorExtenso(Float valor) {
		if (valor != null) {
			// return "("+UtilString.valorPorExtenso(new Double(valor)).toUpperCase()+")";
			// UtilMoeda um = new UtilMoeda(valor);
			// return "(" + um.toString().toUpperCase() + ")";
			return "(" + NumeroPorExtenso.getDefaultInstance().converteMoeda(valor).toUpperCase() + ")";
		} else {
			return null;
		}
	}

	public int getAnoContrato() {
		return DataUtil.getInstance().getAno(new Date());
	}
}
